package com.apes.framework.plugin.scheduler;

import com.alibaba.fastjson.JSONObject;
import com.apes.framework.plugin.esb.api.SimpleRequest;
import com.apes.framework.util.EventUtil;
import com.apes.framework.util.MapUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.List;

/**
 * 功能：任务服务
 *
 * @author xul
 * @create 2018-03-19 13:42
 */
@Service("taskService")
public class TaskService {
    private static final int size = 50;
    private static Date minTimestamp = null;

    @Autowired
    TaskRepository taskRepository;

    @Autowired
    TaskLogRepository taskLogRepository;

    @Autowired
    TaskScheduler taskScheduler;

    public Task save(Task task) {
        return taskRepository.saveAndFlush(task);
    }

    public TaskLog saveLog(TaskLog log) {
        Task task = log.getTask();
        if (!log.isSuccess() && StringUtils.hasText(task.getDingdingAccount())) {
            EventUtil.sendSynEvent(this, "event:dingding.message.publish", MapUtil.mapper(
                    "userList", task.getDingdingAccount(),
                    "content", "定时任务：" + task.getDescription() + "[" + task.getId() + "]" + " 执行异常！" + "\n" + log.getDescription()
            ));
        }
        log.setEndOn(new Date());
        return taskLogRepository.saveAndFlush(log);
    }

    public TaskLog saveLog(String taskId, String description, boolean success, Date beginOn) {
        Task task = taskRepository.findOne(taskId);
        if (task == null) return null;
        TaskLog log = new TaskLog();
        log.setTask(task);
        log.setDescription(description);
        log.setSuccess(success);
        log.setBeginOn(beginOn);
        log.setEndOn(new Date());
        return saveLog(log);
    }

    public boolean exists(String taskId) {
        return taskRepository.exists(taskId);
    }

    public void run(SimpleRequest request) {
        Date maxTimestamp = getMaxTimestamp();
        if (maxTimestamp == null) return;
        if (minTimestamp != null) {
            if (maxTimestamp.getTime() == minTimestamp.getTime()) return;
        }
        int lastSize = size;
        while (lastSize == size) {
            List<Task> tasks = getTasks(maxTimestamp);
            for (Task task : tasks) {
                minTimestamp = task.getLastUpdatedStamp();
                taskScheduler.setTask(task);
            }
            lastSize = tasks.size();
        }
    }

    private Date getMaxTimestamp() {
        Task task = taskRepository.findFirstByOrderByLastUpdatedStampDesc();
        if (task == null) return null;
        return task.getLastUpdatedStamp();
    }

    private List<Task> getTasks(Date maxTimestamp) {
        Pageable pageable = PageRequest.of(0, size);
        if (minTimestamp == null) {
            return taskRepository.findByLastUpdatedStampLessThanEqualOrderByLastUpdatedStampAsc(maxTimestamp, pageable);
        } else {
            return taskRepository.findByLastUpdatedStampGreaterThanAndLastUpdatedStampLessThanEqualOrderByLastUpdatedStampAsc(minTimestamp, maxTimestamp, pageable);
        }
    }

    public Task saveTask(SimpleRequest request) {
        Task task = request.getO(Task.class);
        if (null != task.getMethod() && task.getMethod().contains("{")) {
            task.setMethod((String) JSONObject.parseObject(task.getMethod()).get("id"));
        }
        return taskRepository.saveAndFlush(task);
    }

    public String delete(SimpleRequest request) {
        taskRepository.delete(request.getO(Task.class).getId());
        return "删除成功";
    }
}
